home *** CD-ROM | disk | FTP | other *** search
/ Aminet 39 / Aminet 39 (2000)(Schatztruhe)[!][Oct 2000].iso / Aminet / gfx / edit / RotateAnim.lha / RotateAnim.pprx next >
Encoding:
Text File  |  2000-08-16  |  14.7 KB  |  606 lines

  1. /*
  2. **
  3. ** $VER: RotateAnim.pprx 1.15 (16.08.2000)
  4. ** 
  5. ** (C)2000 Damir Arh, All Rights Reserved.
  6. **
  7. ** E-mail: damir.arh@telesat.si
  8. ** WWW:    http://damir.gajba.net
  9. **
  10. ** FUNCTION:
  11. **    Creates rotation and scaling animation of the source image.
  12. **
  13. ** USAGE:
  14. **    It can be run directly from Shell or from within PPaint's ARexx window.
  15. **    There are no command line arguments, all parameters (source and
  16. **    destination filename, type and attributes of the animation) are specified
  17. **    in a GUI inside PPaint.
  18. **
  19. **
  20. ** $Id: RotateAnim.pprx,v 1.15 2000/08/16 13:14:11 damir Rel $
  21. **
  22. ** $Log: RotateAnim.pprx,v $
  23. ** Revision 1.15  2000/08/16 13:14:11  damir
  24. ** - Spanish translation added (thanks to Javier De Las Rivas <javierdlr@jazzfree.com>)
  25. **
  26. ** Revision 1.14  2000/08/03 12:39:41  damir
  27. ** - French translation added (thanks to Pascal Chiozzi <Micks99@gmx.net>)
  28. **
  29. ** Revision 1.13  2000/08/02 17:46:17  damir
  30. ** - Italian translation added (thanks to Matteo Cavalleri <shiva.brahma@inwind.it>)
  31. **
  32. ** Revision 1.12  2000/07/29 20:01:46  damir
  33. ** - implemented scaling
  34. ** - cleaned up and additionally commented the code
  35. **
  36. ** Revision 1.11  2000/07/28 15:34:58  damir
  37. ** - fixed a bug in animation rotation with a custom axis
  38. ** - removed support for manipulating animations
  39. **
  40. ** Revision 1.10  2000/07/27 14:01:05  damir
  41. ** - implemented a function for the positioning of the rotation axis
  42. **
  43. ** Revision 1.9  2000/07/24 22:24:53  damir
  44. ** - fixed a bug which could cause the animation to be cut off in some cases
  45. ** - removed a forgotten debug printout
  46. **
  47. ** Revision 1.8  2000/07/21 19:45:53  damir
  48. ** - the script can now also be preformed on animations and anim-brushes
  49. ** - parts of the script have been cleaned up by the use of specific functions
  50. **
  51. ** Revision 1.7  2000/07/21 10:57:04  damir
  52. ** - the animation can now be also saved as an anim-brush
  53. **
  54. ** Revision 1.6  2000/07/20 15:00:14  damir
  55. ** - the image doesn't get cut off any more when rotated round the z-axis
  56. **
  57. ** Revision 1.5  2000/07/20 13:43:48  damir
  58. ** - implemented localization support
  59. ** - added the Slovenian translation as a sample
  60. **
  61. ** Revision 1.4  2000/07/20 13:21:23  damir
  62. ** - implemented a selection of the rotation orientation
  63. ** - added keyboard shortcuts to the requesters
  64. **
  65. ** Revision 1.3  2000/07/11 12:42:06  damir
  66. ** - implemented rotation round z-axis
  67. ** - increased the number of frames upper limit
  68. **
  69. ** Revision 1.2  2000/07/08 16:02:41  damir
  70. ** - implemented the rotation round the x-axis
  71. **
  72. ** Revision 1.1  2000/07/07 16:04:54  damir
  73. ** Initial revision
  74. **
  75. **
  76. */
  77.  
  78. msg_title = 'RotateAnim v1.15'
  79.  
  80.  
  81. /* run PPaint if necessary, complain in case of problems */
  82.  
  83. if arg(1,exists) then
  84.     parse arg PPport
  85. else
  86.     PPport = 'PPAINT'
  87.  
  88. if ~show(ports,PPport) then do
  89.     if exists('PPaint:PPaint') then do
  90.         address command 'Run >NIL: PPaint:PPaint'
  91.         do 30 while ~show(ports,PPport)
  92.             address command 'Wait >NIL: 1 SEC'
  93.         end
  94.     end
  95.     else do
  96.         say "Personal Paint could not be loaded."
  97.         exit 10
  98.     end
  99. end
  100.  
  101. if ~show(ports,PPport) then do
  102.     say 'Personal Paint Rexx port could not be opened'
  103.     exit 10
  104. end
  105.  
  106. /* starting setup */
  107.  
  108. address value PPport
  109. options results
  110. options failat 10000
  111.  
  112.  
  113. /* strings and language selection */
  114.  
  115. GET 'LANG'
  116.  
  117. if RESULT = 15 then do  /* Slovensko by Damir Arh <damir.arh@telesat.si> */
  118.     msg_source_type   = 'Izberite vrsto izvorne datoteke'
  119.     msg_source_file   = 'Izberite izvorno datoteko...'
  120.     msg_number_frames = 'Vnesite tevilo sliic'
  121.     msg_multiplier    = 'Vnesite vekratnik tevila sliic'
  122.   msg_select_anim   = 'Izberite vrsto ustvarjene animacije'
  123.     msg_rotate        = '_Rotacija'
  124.     msg_scale         = '_Sprem. velikosti'
  125.     msg_select_axis   = 'Izberite os rotacije'
  126.     msg_x             = 'Os _X'
  127.     msg_y             = 'Os _Y'
  128.     msg_z             = 'Os _Z'
  129.     msg_select_orient = 'Izberite orientacijo rotacije'
  130.     msg_pos           = '_Pozitivna'
  131.     msg_neg           = '_Negativna'
  132.     msg_save_method   = 'Kako €elite animacijo shraniti?'
  133.     msg_image         = '_Slika'
  134.     msg_anim          = '_Animacija'
  135.     msg_brush         = 'Anim. o_pi'
  136.     msg_axis_pos      = 'Koordinate osi'
  137.     msg_dest_pos      = 'Koordinate ponora'
  138.     msg_x_coord       = 'X'
  139.     msg_y_coord       = 'Y'
  140. end
  141. else if result = 2 then do  /* Italiano by Matteo Cavalleri <shiva.brahma@inwind.it> */
  142.     msg_source_type   = 'Scegli il tipo del file sorgente'
  143.     msg_source_file   = 'Scegli il file sorgente...'
  144.     msg_number_frames = 'Immetti il numero dei frames'
  145.     msg_multiplier    = 'Immetti il moltiplicatore dei frames'
  146.     msg_select_anim   = 'Scegli il tipo dell''animazione creata'
  147.     msg_rotate        = '_Rotazione'
  148.     msg_scale         = '_Scalatura'
  149.     msg_select_axis   = 'Seleziona l''asse per la rotazione'
  150.     msg_x             = 'Asse _X'
  151.     msg_y             = 'Asse _Y'
  152.     msg_z             = 'Asse _Z'
  153.     msg_select_orient = 'Seleziona l''orientamento della rotazione'
  154.     msg_pos           = '_Positivo'
  155.     msg_neg           = '_Negativo'
  156.     msg_save_method   = 'Come vuoi salvare l''animazione?'
  157.     msg_image         = '_Immagine'
  158.     msg_anim          = '_Animazione'
  159.     msg_brush         = 'Anim-_brush'
  160.     msg_axis_pos      = 'Coordinate assi'
  161.     msg_dest_pos      = 'Coordinate destinazione'
  162.     msg_x_coord       = 'X'
  163.     msg_y_coord       = 'Y'
  164. end
  165. else if result = 3 then do  /* Français by Pascal Chiozzi <Micks99@gmx.net> */
  166.     msg_source_type   = 'Sélectionner le type de fichier source'
  167.     msg_source_file   = 'Sélectionner le fichier source...'
  168.     msg_number_frames = 'Entrer le nombres d''images'
  169.     msg_multiplier    = 'Entrer le multiplicateur'
  170.     msg_select_anim   = 'Sélectionner le type d''animation à créer'
  171.     msg_rotate        = '_Rotation'
  172.     msg_scale         = 'Re_dimensionner'
  173.     msg_select_axis   = 'Sélectionner l''axe de rotation'
  174.     msg_x             = 'Axe-_X'
  175.     msg_y             = 'Axe-_Y'
  176.     msg_z             = 'Axe-_Z'
  177.     msg_select_orient = 'Sélectionner l''orientation de la rotation'
  178.     msg_pos           = '_Positive'
  179.     msg_neg           = '_Negative'
  180.     msg_save_method   = 'Comment veux-tu sauver l''animation?'
  181.     msg_image         = '_Image'
  182.     msg_anim          = '_Animation'
  183.     msg_brush         = '_Brosse anim'
  184.     msg_axis_pos      = 'Coordonnées de l''axe'
  185.     msg_dest_pos      = 'Coordonnées de destination'
  186.     msg_x_coord       = 'X'
  187.     msg_y_coord       = 'Y'
  188. end
  189. else if result = 4 then do  /* Español by Javier de las Rivas <javierdlr@jazzfree.com> */
  190.     msg_source_type   = 'Tipo de fichero fuente'
  191.     msg_source_file   = 'Elija el fichero fuente...'
  192.     msg_number_frames = 'Nº de fotogramas:'
  193.     msg_multiplier    = 'Nº fotogramas ×'
  194.     msg_select_anim   = 'Tipo de animación a crear'
  195.     msg_rotate        = '_Rotar'
  196.     msg_scale         = 'Re_escalar'
  197.     msg_select_axis   = 'Elija el eje de rotación'
  198.     msg_x             = 'Eje-_X'
  199.     msg_y             = 'Eje-_Y'
  200.     msg_z             = 'Eje-_Z'
  201.     msg_select_orient = 'Orientación de rotación'
  202.     msg_pos           = '_Positiva'
  203.     msg_neg           = '_Negativa'
  204.     msg_save_method   = 'Salvar fichero como'
  205.     msg_image         = '_Imagen'
  206.     msg_anim          = '_Animación'
  207.     msg_brush         = '_Brocha-Anim'
  208.     msg_axis_pos      = 'Eje de coordenadas'
  209.     msg_dest_pos      = 'Tamaño del destino'
  210.     msg_x_coord       = 'X:'
  211.     msg_y_coord       = 'Y:'
  212. end
  213. else do  /* English by Damir Arh <damir.arh@telesat.si> */
  214.     msg_source_type   = 'Select the type of source file'
  215.     msg_source_file   = 'Select source file...'
  216.     msg_number_frames = 'Enter number of frames'
  217.     msg_multiplier    = 'Enter frames multiplier'
  218.     msg_select_anim   = 'Select the type of the created animation'
  219.     msg_rotate        = '_Rotation'
  220.     msg_scale         = '_Scaling'
  221.     msg_select_axis   = 'Select the axis for the rotation'
  222.     msg_x             = '_X-axis'
  223.     msg_y             = '_Y-axis'
  224.     msg_z             = '_Z-axis'
  225.     msg_select_orient = 'Select the orientation of the rotation'
  226.     msg_pos           = '_Positive'
  227.     msg_neg           = '_Negative'
  228.     msg_save_method   = 'How would you like to save the animation?'
  229.     msg_image         = '_Image'
  230.     msg_anim          = '_Animation'
  231.     msg_brush         = 'Anim-_brush'
  232.     msg_axis_pos      = 'Axis coordinates'
  233.     msg_dest_pos      = 'Destination coordinates'
  234.     msg_x_coord       = 'X'
  235.     msg_y_coord       = 'Y'
  236. end
  237.  
  238.  
  239. /* ask the user for parameters */
  240.  
  241. REQUEST '"'msg_title'" ' ||, /* source file type */
  242.     '"TEXT = ""'msg_source_type'"" ' ||,
  243.     ' ACTION = ""'msg_image'"" ' ||,
  244.     ' ACTION = ""'msg_brush'"" "'
  245.  
  246.     if rc = 0 then
  247.         Type = RESULT
  248.     else
  249.         exit
  250.  
  251. REQUESTFILE '"'msg_source_file'"' /* source filename */
  252.  
  253.     if rc = 0 then
  254.         Source = RESULT
  255.     else
  256.         exit
  257.  
  258. if Type = 1 then do /* number of frames */
  259.     REQUEST '"'msg_title'" ' ||, /* image */
  260.         '"INTSTR = ""'msg_number_frames'"", 1, 500, 50 '
  261.  
  262.         if rc = 0 then
  263.             Frames = RESULT.1
  264.         else
  265.             exit
  266. end
  267. else do
  268.     REQUEST '"'msg_title'" ' ||, /* animation */
  269.         '"INTSTR = ""'msg_multiplier'"", 1, 10, 1 '
  270.  
  271.         if rc = 0 then
  272.             Multiplier = RESULT.1
  273.         else
  274.             exit
  275. end
  276.  
  277. REQUEST '"'msg_title'" ' ||, /* animation type */
  278.     '"TEXT = ""'msg_select_anim'"" ' ||,
  279.     ' ACTION = ""'msg_rotate'"" ' ||,
  280.     ' ACTION = ""'msg_scale'"" "'
  281.  
  282.     if rc = 0 then
  283.         Process = RESULT
  284.     else
  285.         exit
  286.  
  287. if Process = 1 then do /* rotation */
  288.  
  289.     REQUEST '"'msg_title'" ' ||, /* axis */
  290.         '"TEXT = ""'msg_select_axis'"" ' ||,
  291.         ' ACTION = ""'msg_x'"" ' ||,
  292.         ' ACTION = ""'msg_y'"" ' ||,
  293.       ' ACTION = ""'msg_z'"" "'
  294.  
  295.         if rc = 0 then
  296.             Axis = RESULT
  297.         else
  298.             exit
  299.  
  300.     if Axis = 3 then do
  301.  
  302.         REQUEST '"'msg_title'" ' ||, /* orientation */
  303.             '"TEXT = ""'msg_select_orient'"" ' ||,
  304.             ' ACTION = ""'msg_pos'"" ' ||,
  305.             ' ACTION = ""'msg_neg'"" "'
  306.  
  307.             if rc = 0 then
  308.                 Orientation = RESULT
  309.             else
  310.                 exit
  311.  
  312.     end
  313.  
  314. end
  315.  
  316. /* get source attributes */
  317.  
  318. LOADBRUSH Source
  319. GETBRUSHATTRIBUTES HANDLEX
  320. hx = RESULT
  321. GETBRUSHATTRIBUTES HANDLEY
  322. hy = RESULT
  323. GETBRUSHATTRIBUTES WIDTH
  324. x = RESULT - 1
  325. GETBRUSHATTRIBUTES HEIGHT
  326. y = RESULT - 1
  327.  
  328. /* axis coordinates */
  329.  
  330. if Axis = 1 then do
  331.     msg_y_coord1 = msg_y_coord || ' (1-' || y || ')'
  332.     REQUEST '"'msg_axis_pos'" ' ||,
  333.         '"INTSTR = ""'msg_y_coord1'"", 1, 'y', 'hy' "'
  334.     if rc = 0 then
  335.         AxisY = RESULT.1
  336.     else
  337.         exit
  338.     GETBRUSHATTRIBUTES HANDLEX
  339.     AxisX = RESULT
  340. end
  341. else if Axis = 2 then do
  342.     msg_x_coord1 = msg_x_coord || ' (1-' || x || ')'
  343.     REQUEST '"'msg_axis_pos'" ' ||,
  344.         '"INTSTR = ""'msg_x_coord1'"", 1, ' || x || ', 'hx' "'
  345.     if rc = 0 then
  346.         AxisX = RESULT.1
  347.     else
  348.         exit
  349.     GETBRUSHATTRIBUTES HANDLEY
  350.   AxisY = RESULT
  351. end
  352. else if Axis = 3 then do
  353.     msg_x_coord1 = msg_x_coord || ' (1-' || x || ')'
  354.     msg_y_coord1 = msg_y_coord || ' (1-' || y || ')'
  355.     REQUEST '"'msg_axis_pos'" ' ||,
  356.         '"INTSTR = ""'msg_x_coord1'"", 1, ' || x || ', 'hx' ' ||,
  357.         ' INTSTR = ""'msg_y_coord1'"", 1, 'y', 'hy' "'
  358.     if rc = 0 then do
  359.         AxisX = RESULT.1
  360.         AxisY = RESULT.2
  361.     end
  362.     else
  363.         exit
  364. end
  365. else do /* scaling */
  366.     msg_x_coord1 = msg_x_coord || ' (1-' || x || ')'
  367.     msg_y_coord1 = msg_y_coord || ' (1-' || y || ')'
  368.     REQUEST '"'msg_dest_pos'" ' ||,
  369.         '"INTSTR = ""'msg_x_coord1'"", 1, ' || x || ', 'hx' ' ||,
  370.         ' INTSTR = ""'msg_y_coord1'"", 1, 'y', 'hy' "'
  371.     if rc = 0 then do
  372.         AxisX = RESULT.1
  373.         AxisY = RESULT.2
  374.     end
  375.     else
  376.         exit
  377. end
  378.  
  379. REQUEST '"'msg_title'" ' ||, /* save filename */
  380.     '"TEXT = ""'msg_save_method'"" ' ||,
  381.     ' ACTION = ""'msg_anim'"" ' ||,
  382.     ' ACTION = ""'msg_brush'"" "'
  383.  
  384.     if rc = 0 then
  385.         Method = RESULT
  386.     else
  387.         exit
  388.  
  389.  
  390. /* setup the environment */
  391.  
  392. LOCKGUI
  393. DELETEFRAMES ALL FORCE
  394. LOADIMAGE Source FORCE
  395. CLEARIMAGE FORCE
  396.  
  397. /* calculate brush attributes */
  398.  
  399. bx = max(AxisX,2*hx-AxisX)
  400. by = max(AxisY,2*hy-AxisY)
  401. BrushWidth = 2 * bx
  402. BrushHeight = 2 * by
  403.  
  404. /* load the source image and modify it for the effect */
  405.  
  406. SETCURRENTBRUSH 1
  407. if Type = 1 then do /* image */
  408.     LOADBRUSH Source
  409.     if Axis ~= 3 then do
  410.         SETBRUSHHANDLE AxisX AxisY
  411.         PUTBRUSH bx by
  412.         DEFINEBRUSH 0 0 BrushWidth BrushHeight
  413.         CLEARIMAGE FORCE
  414.     end
  415. end
  416. else do /* animated brush */
  417.     LOADANIMBRUSH Source
  418.     GETANIMBRUSHSETTINGS 'FRAMES'
  419.     BrFrames = RESULT
  420.     ADDFRAMES BrFrames
  421.     do i = 1 to BrFrames
  422.         SETFRAMEPOSITION i
  423.         SETBRUSHATTRIBUTES FRAMEPOSITION i
  424.         if Axis = 3 then do
  425.             PUTBRUSH hx hy
  426.         end
  427.         else do
  428.             SETBRUSHHANDLE AxisX AxisY
  429.             PUTBRUSH bx by
  430.         end
  431.     end
  432.     SETFRAMEPOSITION 1
  433.     if Axis = 3 then do
  434.         GETBRUSHATTRIBUTES WIDTH
  435.         BrushWidth = RESULT
  436.         GETBRUSHATTRIBUTES HEIGHT
  437.         BrushHeight = RESULT
  438.     end
  439.     GETFRAMES
  440.     BrFrames = RESULT
  441.     COPYENVIRONMENT ANIMATION FORCE
  442.     SWITCHENVIRONMENT
  443.     DELETEFRAMES ALL FORCE
  444.     CLEARIMAGE FORCE
  445.     Frames = BrFrames * Multiplier
  446. end
  447.  
  448. ADDFRAMES Frames
  449.  
  450. /* in case of z-axis rotation or scaling set correct position for the effect */
  451.  
  452. if Process = 2 then do
  453.     bx = AxisX
  454.     by = AxisY
  455. end
  456. else if Axis = 3 then do
  457.     SETBRUSHHANDLE AxisX AxisY
  458.     GETDISTANCE 0 0 max(AxisX,2*hx-AxisX) max(AxisY,2*hy-AxisY)
  459.     bx = RESULT
  460.     by = RESULT
  461. end
  462. SET 'FORCE "IMAGEW='2*bx'" "IMAGEH='2*by'"'
  463.  
  464. /* set final animation size */
  465.  
  466. if Process = 1 then do
  467.     FBrushWidth = 2 * bx
  468.     FBrushHeight = 2 * by
  469. end
  470. else do
  471.     FBrushWidth = x
  472.     FBrushHeight = y
  473. end
  474.  
  475.  
  476. /* draw the first frame - unchanged image */
  477.  
  478. SETFRAMEPOSITION 1
  479. if Type ~= 1 then do
  480.     SWITCHENVIRONMENT
  481.     SETFRAMEPOSITION 1
  482.     DEFINEBRUSH 0 0 BrushWidth BrushHeight
  483.     SWITCHENVIRONMENT
  484. end
  485. PUTBRUSH bx by
  486.  
  487.  
  488. /* draw the rest of the frames */
  489.  
  490. SETCURRENTBRUSH 2
  491. k = 4 / Frames
  492. if Axis = 1 then
  493.     BrushSize = FBrushHeight
  494. else do
  495.     if Axis = 2 then
  496.         BrushSize = FBrushWidth
  497.     else
  498.         BrushSize = 90000
  499. end
  500.  
  501. do i = 2 to Frames
  502.  
  503.     /* obtain the default image */
  504.  
  505.     FREEBRUSH FORCE
  506.     COPYBRUSH 1
  507.     if Type ~= 1 then do
  508.         SWITCHENVIRONMENT
  509.         SETFRAMEPOSITION ( (i - 1) // BrFrames ) + 1
  510.         DEFINEBRUSH 0 0 BrushWidth BrushHeight
  511.         SWITCHENVIRONMENT
  512.     end
  513.     SETFRAMEPOSITION i
  514.     size = (i - 1) * k
  515.  
  516.     if Process = 2 then do /* scaling */
  517.         NBrushWidth = max(1,trunc(abs(size / 2 - 1) * BrushWidth,0))
  518.         NBrushHeight = max(1,trunc(abs(size / 2 - 1) * BrushHeight,0))
  519.     end
  520.     else if Axis = 3 then /* z-axis rotation */
  521.         NewSize = trunc(BrushSize * size,0)
  522.     else do
  523.  
  524.         /* 0 - 90 degrees */
  525.  
  526.         if size < 1 then do
  527.             size = 1 - size
  528.             NewSize = trunc(BrushSize * size,0)
  529.             size = -1
  530.         end
  531.  
  532.         /* 90 or 270 degrees */
  533.  
  534.         if size = 1 | size = 3 then do
  535.             NewSize = 1
  536.             size = -1
  537.         end
  538.  
  539.         /* 270 - 360 degrees */
  540.  
  541.         if size > 3 then do
  542.             size = size - 3
  543.             NewSize = trunc(BrushSize * size,0)
  544.             size = -1
  545.         end
  546.  
  547.         /* 180 - 270 degrees */
  548.  
  549.         if size > 2 then do
  550.             size = 3 - size
  551.             NewSize = trunc(BrushSize * size,0)
  552.             size = -2 /* indicates the need for flipping */
  553.         end
  554.  
  555.         /* 90 - 180 degrees */
  556.  
  557.         if size > 1 then do
  558.             size = size - 1
  559.             NewSize = trunc(BrushSize * size,0)
  560.             size = -2 /* indicates the need for flipping */
  561.         end
  562.  
  563.     end
  564.  
  565.     /* perform the transformation */
  566.  
  567.     if Process = 1 then do /* rotation */
  568.         if Axis = 1 then do
  569.             if size = -2 then do
  570.                 FLIPBRUSH VERTICAL
  571.             end
  572.             SETBRUSHATTRIBUTES HEIGHT NewSize
  573.         end
  574.         else do
  575.             if Axis = 2 then do
  576.                 if size = -2 then do
  577.                     FLIPBRUSH HORIZONTAL
  578.                 end
  579.                 SETBRUSHATTRIBUTES WIDTH NewSize
  580.             end
  581.             else
  582.                 if Orientation = 2 then
  583.                     ROTATEBRUSH NewSize
  584.                 else
  585.                     ROTATEBRUSH 360000-NewSize
  586.         end
  587.     end
  588.     else do /* scaling */
  589.         SETBRUSHATTRIBUTES WIDTH NBrushWidth HEIGHT NBrushHeight
  590.     end
  591.  
  592.     PUTBRUSH bx by
  593.  
  594. end
  595.  
  596. /* save the animation at the end */
  597.  
  598. UNLOCKGUI
  599.  
  600. if Method = 2 then do
  601.     DEFINEBRUSH 0 0 FBrushWidth FBrushHeight Frames
  602.     SAVEANIMBRUSH
  603. end
  604. else
  605.     SAVEANIMATION
  606.